
#include <pic.h>
#include "delay.h"
#include "always.h"
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//__CONFIG(0x3bb4);

//bhanu



#define DIG1			RB4
#define DIG1_TRIS		TRISB4

#define DIG2			RB5
#define DIG2_TRIS		TRISB5

#define DIG3			RB6
#define DIG3_TRIS		TRISB6

#define DIG4			RB7
#define DIG4_TRIS		TRISB7

#define DIG5			RA4
#define DIG5_TRIS		TRISA4


#define KEY				RC2
#define KEY_TRIS		TRISC2



//char
#define LBLANK_LED       10
#define LLP               11
#define LF               12
#define LN               13
#define LO               14
#define LE               15
#define LT               16
#define LD               17
#define LL               18
#define LR               19
#define LU               20
#define LA               21
#define LM               22
#define LC               23
#define LY               24
#define LS               5
#define DIS				25

#define KLED	LedStatus.part.bit0
#define RYLED	LedStatus.part.bit1
#define YBLED	LedStatus.part.bit2
#define BRLED	LedStatus.part.bit3	



  // BCD codings :
unsigned char bcd[] =
{
    0b00111111,         //0
    0b00000110,         //1
    0b01011011,         //2
    0b01001111,         //3
    0b01100110,         //4
    0b01101101,         //5
    0b01111101,         //6
    0b00000111,         //7
    0b01111111,         //8
    0b01101111,         //9
    0b00000000,         //balnk10
    0b01110011,         //P 11
    0b01110001,         //f 12
    0b01010100,         //n 13
    0b01011100,         //0 14
    0b01111001,         //e 15
    0b01111000,         //t 16
    0b01011110,         //d 17
    0b00111000,         //l 18
    0b01010000,         //r 19
    0b00111110,         //u 20
    0b01110111,         //A 21
    0b01010101,         //M 22
    0b00111001,         //C 23
    0b01101110,         //Y 24
	0b01000000,         //- 25
};

unsigned char disp_buff[4];
unsigned char display_position;
unsigned char DecimalFlag,DecimalFlage;
union chartype LedStatus;
long ct_ratio_read;
float CurrentCal;
static bit key_flage;
double tmp1;
int AvgCount;
double AvgCurr;
float CurrVal;
unsigned int ZeroAdc;


void interrupt timer0_isr(void)
{

    if(T0IF == 1)
    {

		DIG2 = 0;
        DIG3 = 0;
        DIG4 = 0;
		DIG5 = 0;
		DIG1 = 0;
		PORTC = 0x00;
		KEY = 0;
		KEY_TRIS = 1;
		if(KEY == 1)
			key_flage = 1;	
		KEY = 0;
		KEY_TRIS = 0;
	
		if(display_position == 0)
		{
			DIG2 = 0;
	        DIG3 = 0;
	        DIG4 = 0;
			DIG5 = 0;
			DIG1 = 1;
	        
		}
		else if(display_position == 1)
		{
			DIG1 = 0;
			DIG3 = 0;
	        DIG4 = 0;
			DIG5 = 0;
	        DIG2 = 1;
	        
		}
		else if(display_position == 2)
		{
			DIG1 = 0;
	        DIG2 = 0;
			DIG4 = 0;
			DIG5 = 0;
	        DIG3 = 1;
	        
		}
		else if(display_position == 3)
		{
			DIG1 = 0;
	        DIG2 = 0;
	        DIG3 = 0;
			DIG5 = 0;
	        DIG4 = 1;
			
		}
		else if(display_position == 4)
		{
			DIG1 = 0;
	        DIG2 = 0;
	        DIG3 = 0;
	        DIG4 = 0;
			DIG5 = 1;
		}
		
	
		if(display_position != 4)
	     	PORTC = disp_buff[display_position];
		else
			PORTC = LedStatus.byte;

	
		
		if(DecimalFlag != 0)
		{
			if((DecimalFlag-1) == display_position)
				RC7 = 1;	
			else
				RC7 = 0;
		}
		else
			RC7 = 0;

		display_position++;
     	if(display_position>=5)
        	 display_position = 0;

        T0IF = 0;  
    }
    else
    {
        if(TMR1IF == 1)
        {

            TMR1IF = 0;
        }
        else
        {
            if((RCIE)&&(RCIF))                                      /*receive interrupt routine*/
            {
                
                RCIF = 0;
            }
        }
    }
}



void decimal_bcd(unsigned int value);
void voltage_adc(unsigned char channel);
signed int get_adc(unsigned char channel);
void set_ct_ratio(void);
void get_key(void);
void ReadCtRatio(void);
void set_Cal(void);
void voltage_adc_cal(unsigned char channel);

void main(void)
{


   	unsigned int Tp;
	float Tp2;

    IRCF0 = 1;
    IRCF1 = 1;
    IRCF2 = 1;

back:

    CM1CON0 = 0x00;
	CM2CON0 = 0x00;

    ANSEL  = 0b00000111;
    ANSELH = 0b00000000;


    T0CS = 0;               /* clear to enable timer mode */
    PSA = 0;                /* clear to assign prescaller to TMRO */
    PS2 = 0;                /* 011 @ 10Mhz = 1.638 mS */
    PS1 = 1;
    PS0 = 0;

    INTCON = 0;             /* clear interrupt flag bits */
    GIE = 1;                /* global interrupt enable */
    T0IE = 1;               /* TMR0 overflow interrupt enable */

    TMR0 = 0;               /* clear the value in TMR0 */

    T1CON=0x00;
    PEIE = 1;
    PEIE = 1;
    PIR1 = 0;
    PIE1 = 3;

	PORTC = 0x00;
	TRISC = 0x00;

	TRISB = 0x00;
		
	TRISA = 0b00000111;

	Tp = 0;


	GIE = 0;
	for(Tp=0;Tp<=10;Tp++)
	{
		T0IE = 0;
		PORTC = 0xff;
		DIG1 = 1;
        DIG2 = 1;
        DIG3 = 1;
        DIG4 = 1;
		DIG5 = 1;
		DelayMs(250);
	}
	T0IE = 1;
	GIE = 1;


	key_flage = 0;
	DelayMs(250);
	if(key_flage == 1)
	{
		disp_buff[0] = bcd[LC];;
	    disp_buff[1] = bcd[LT];
		disp_buff[2] = bcd[LC];
		disp_buff[3] = bcd[LL];
		
		DelayS(2);
		ReadCtRatio();
		key_flage = 0;
		while(1)
		{	
			voltage_adc_cal(2);
			voltage_adc(2);
			tmp1 = tmp1*CurrentCal;
			tmp1 = tmp1*(float)ct_ratio_read;
			CurrVal =tmp1;	
			if(CurrVal<500)
			{
				DecimalFlage = 3;
				Tp2 = CurrVal*10;
				Tp = (unsigned int)Tp2;
				DecimalFlag= DecimalFlage;	
				decimal_bcd(Tp);
				if(key_flage == 1)
				{
					CurrVal = 249.99999/CurrVal;
					CurrentCal = CurrentCal*CurrVal;
					disp_buff[0] = bcd[LC];;
				    disp_buff[1] = bcd[LT];
					disp_buff[2] = bcd[LC];
					disp_buff[3] = bcd[LD];
					Tp2 = CurrentCal*1000;
					Tp = (unsigned int)Tp2;
					eeprom_write(0x02,Tp>>8);
					eeprom_write(0x03,Tp);
					DelayS(2);
					goto back;
				}
	
			}
		}
	
	
	
	
		
	}

	ReadCtRatio();

	AvgCurr = 0;
	CurrVal = 0;
	key_flage = 0;

	while(1)
	{
		voltage_adc_cal(2);
		voltage_adc(2);
		tmp1 = tmp1*CurrentCal;
		tmp1 = tmp1*(float)ct_ratio_read;
		AvgCurr+=tmp1;
		//CurrVal =tmp1;	

		AvgCount++;
		if(AvgCount>=2)
		{
			CurrVal = AvgCount;//AvgCount;
			CurrVal = AvgCurr/CurrVal;
			if(CurrVal<15)
				CurrVal = 0;
			AvgCurr = 0;	
			AvgCount = 0;
		}
		
		if(CurrVal>999 && CurrVal<9999)
		{
			DecimalFlage = 0;
			Tp = (unsigned int)CurrVal;
		}
		else if(CurrVal<999 && CurrVal>99)
		{
			DecimalFlage = 3;
			Tp2 = CurrVal*10;
			Tp = (unsigned int)Tp2;
		}
		else if(CurrVal<99 && CurrVal>9)
		{
			DecimalFlage = 2;
			Tp2 = CurrVal*100;
			Tp = (unsigned int)Tp2;
		}
		else if(CurrVal<9)
		{
			DecimalFlage = 1;
			Tp2 = CurrVal*1000;
			Tp = (unsigned int)Tp2;
		}

		if(CurrVal>9999)
		{
		
			Tp2 = CurrVal/1000;	
			if(Tp2>999 && Tp2<9999)
			{
				DecimalFlage = 0;
				Tp = (unsigned int)Tp2;
			}
			else if(Tp2<999 && Tp2>99)
			{
				DecimalFlage = 3;
				Tp2 = Tp2*10;
				Tp = (unsigned int)Tp2;
			}
			else if(Tp2<99 && Tp2>9)
			{
				DecimalFlage = 2;
				Tp2 = Tp2*100;
				Tp = (unsigned int)Tp2;
			}
			else if(Tp2<9)
			{
				DecimalFlage = 1;
				Tp2 = Tp2*1000;
				Tp = (unsigned int)Tp2;
			}
			DecimalFlag= DecimalFlage;
			Tp = (unsigned int)Tp2;	
			decimal_bcd(Tp);	
			YBLED = 1;
		}
		else
		{
			YBLED = 0;
			DecimalFlag= DecimalFlage;		
			decimal_bcd(Tp);
		}
		if(key_flage == 1)
		{
			key_flage = 0;
			set_ct_ratio();
		}
		DelayMs(10);
	}
	
}



void ReadCtRatio(void)
{
	unsigned int Tp;
	ct_ratio_read = (eeprom_read(0x00)*256)+eeprom_read(0x01);
	if(ct_ratio_read<=0 || ct_ratio_read>9999)
		ct_ratio_read = 1;
	Tp = (eeprom_read(0x02)*256)+eeprom_read(0x03);
	if(Tp<=0 || Tp>=2000)
		Tp = 1000;
	CurrentCal = Tp;
	CurrentCal = CurrentCal/1000;

	ZeroAdc = (eeprom_read(0x04)*256)+eeprom_read(0x05);
	if(ZeroAdc<=300 || ZeroAdc>=800)
		ZeroAdc = 512;
}




signed long tmp;
void voltage_adc(unsigned char channel)
{
    
    unsigned int no_samples,no_samples1;
    unsigned int ExitDelay;
	union chartype AdcCh;

    tmp1 = 0;
    no_samples1 = 0;
    tmp = 0;
    VCFG = 0;
    ADCS1 = 0;
    ADCS0 = 1;
    ADFM = 1;
    ADON = 1;
    

	AdcCh.byte = channel;
	CHS0 = AdcCh.part.bit0;
	CHS1 = AdcCh.part.bit1;
	CHS2 = AdcCh.part.bit2;
	CHS3 = AdcCh.part.bit3;
    DelayMs(5);
    tmp = 0;
	ExitDelay = 0;


	tmp = get_adc(channel);
	if(tmp<=2)
	{
	    while(tmp <= 2)
	    {
	        tmp = get_adc(channel);
			ExitDelay++;
			if(ExitDelay>3000)
				return;
	
	    }
	}
	else
	{
		while(tmp >= 2)
	    {
	        tmp = get_adc(channel);
			ExitDelay++;
			if(ExitDelay>3000)
				return;
	
	    }
		ExitDelay = 0;
		while(tmp <= 2)
	    {
	        tmp = get_adc(channel);
			ExitDelay++;
			if(ExitDelay>3000)
				return;
	
	    }
	}
	ExitDelay = 0;
	for(no_samples=0;no_samples<=1000;no_samples++)
	{
		tmp = get_adc(channel);
		if(tmp<-2 || tmp>2)
		{
			no_samples1++;
			tmp = abs(tmp);
			tmp = tmp*tmp;
			tmp1 = tmp1+tmp;
		}
	}
	
	tmp1 = tmp1/no_samples1;
	tmp1 = sqrt(tmp1);
	if(tmp1<2)
		tmp1 = 0;

}



void voltage_adc_cal(unsigned char channel)
{
    
    unsigned int no_samples,no_samples1;
    long ExitDelay;
	union chartype AdcCh;

    tmp1 = 0;
    no_samples1 = 0;
    tmp = 0;
    VCFG = 0;
    ADCS1 = 1;
    ADCS0 = 1;
    ADFM = 1;
    ADON = 1;
    

	AdcCh.byte = channel;
	CHS0 = AdcCh.part.bit0;
	CHS1 = AdcCh.part.bit1;
	CHS2 = AdcCh.part.bit2;
	CHS3 = AdcCh.part.bit3;
    DelayMs(5);
    tmp = 0;
	ExitDelay = 0;


	
	for(no_samples=0;no_samples<1000;no_samples++)
	{

	
	    DelayUs(20);
		while(GO_DONE == 1) continue;
		GO_DONE = 1;
	    while(GO_DONE == 1) continue;
	    tmp = (ADRESH*256)+ADRESL;
		if(tmp>1)
		{
			no_samples1++;
			tmp1 = tmp1+tmp;
		}
	}
	
	tmp1 = tmp1/no_samples1;
	ZeroAdc = (unsigned int)tmp1;
	
	
}


void set_ct_ratio(void)
{
	unsigned int key_delay = 0;
	unsigned char exit_delay = 0;

	DecimalFlag = 0;

	disp_buff[0] = bcd[LLP];;
    disp_buff[1] = bcd[LT];
	disp_buff[2] = bcd[LBLANK_LED];
	disp_buff[3] = bcd[LR];
	
	DelayS(2);
	ReadCtRatio();
	key_flage = 0;
	while(1)
	{
		decimal_bcd(ct_ratio_read);
		if(key_flage == 1)
		{
		
			exit_delay = 0;
			key_delay++;
			ct_ratio_read++;
			if(ct_ratio_read>=2000)
				ct_ratio_read = 1;
			key_flage = 0;
		}
		else
		{
			key_delay = 0;
			exit_delay++;
		}
		if(key_delay<10)
		{
			DelayMs(250);
		}
		else if(key_delay>10 && key_delay<101)
		{
			DelayMs(50);
		}
		else
			DelayMs(10);
		if(exit_delay>=15)
			break;
		
	}


	eeprom_write(0x00,ct_ratio_read>>8);
	eeprom_write(0x01,ct_ratio_read);




}


signed int get_adc(unsigned char channel)
{
	int Tp;
    unsigned int adc_value;
    DelayUs(20);
	while(GO_DONE == 1) continue;
	GO_DONE = 1;
    while(GO_DONE == 1) continue;
    adc_value = (ADRESH*256)+ADRESL;
	Tp = adc_value;
	Tp = Tp-ZeroAdc;
    return (Tp);
}



void decimal_bcd(unsigned int value)
{
    unsigned int result1,result2,result3,result4;
    result1 = value/1000;
    value = value%1000;
    result2 = value/100;
    value = value%100;
    result3 = value/10;
    value = value%10;
    result4 = value;
    disp_buff[0] = bcd[result1];
    disp_buff[1] = bcd[result2];
    disp_buff[2] = bcd[result3];
    disp_buff[3] = bcd[result4];
}